#ifndef GAMEMODEL_H
#define GAMEMODEL_H

#include "GlobalClass.h"

#include <QThread>
#include <QQueue>
#include <QDebug>



//伪随机数（客户端之间、服务端之间同步）
//暂时无用
struct _FakeRandom
{
    _FakeRandom() {}
    void clear()
    {
        arrayRandomNumbers.clear();
        nIndex = 0;
        nType = 0;
    }

    qint16 randFake()
    {
        if(arrayRandomNumbers.count() == 0)
        {
            for(int i = 0; i < 10000; i++)
                arrayRandomNumbers << (qint16)i;
        }

        if(nIndex >= arrayRandomNumbers.count())
        {
            nType++;
            nIndex = 0;
        }

        switch (nType)
        {
        case 0:
            return arrayRandomNumbers.at(nIndex++);
        case 1:
            return arrayRandomNumbers.at(nIndex++) + 1;
        default:    //其他组合方式
            nType = 0;
            return arrayRandomNumbers.at(nIndex++);
        }

        return 0;
    }



    //返回一个大随机数（4字节有符号）
    int intRandFake()
    {
        return (randFake() << 16) + (randFake() << 1) + (randFake() % 2);
    }

    qint64 longRandFake()
    {
        qint64 r1 = intRandFake();

        return (r1 << 32) + (intRandFake() << 1) + (randFake() % 2);
    }

    ////////////////////////////////////////////////
    int RandomFake(int n1, int n2)
    {
        if(n1==n2)return n1;
        else if(n2<n1)
        {
            n1=n1+n2;
            n2=n1-n2;
            n1=n1-n2;
        }
        return (intRandFake() % ( n2 - n1 )) + n1;
        //int value=minValue+int((maxValue-minValue)*(rand()/(float)RAND_MAX));
    }
    int RandTargetFake(int n, int m)        //m分之n
    {
        if(n > m || n < 0)return -1;    //不符合
        if(intRandFake() % m < n)return 1;    //命中
        return 0;
    }

    QVector<qint16>  arrayRandomNumbers;      //伪随机数
    int nIndex;     //第几个
    int nType;      //组合方式
};



//GameInit和s_GameInitFinished分别放在派生的首尾
//InitOnce和s_InitOnceFinished分别放在派生的首尾
//GameOver放在派生尾部
class GameModel: public QObject
{
    Q_OBJECT
    Q_ENUMS(_GameStatus)
    Q_PROPERTY(bool netPlay READ netPlay)
    Q_PROPERTY(_GameStatus gameStatus READ gameStatus)


public:
    enum _GameType      //游戏类型
    {
        Game_Type_NULL = 0,
        Game_Type_1
    };

    enum _GameStatus    //游戏状态
    {
        Game_Status_NotRunning = 0,
        Game_Status_Init = 1,     //游戏初始化
        Game_Status_Running,     //游戏正常运行
        //Game_Status_NextTurn,
        Game_Status_GameOver,       //游戏正常结束
        Game_Status_Exit,           //游戏退出(网络指令,玩家被动)
        Game_Status_Terminated,     //游戏退出(玩家主动强制)
        Game_Status_ERROR = -1,     //游戏出错
    };


public:
    explicit GameModel(QObject *parent = nullptr);
    virtual ~GameModel();

//本类发出的信号
signals:
    void s_InitOnceFinished();          //给qml通知
    void s_GameInitFinished();          //游戏初始化
    void s_GameStart(bool isStarted);   //游戏开始信号
    void s_GameOver(_GameStatus status, qint32 code);


//给外部发送的信息:
    //void s_RefreshUI();               //刷新UI
    void s_Message(QString msg);        //游戏中显示信息
    void s_Debug(QString msg);          //显示调试信息
    void s_Critical(QString msg);       //显示错误信息

//框架：
public:
    int InitOnce()         //进行初始化(仅1次,由外部配置好后调用)
    {
        int ret = _InitOnce();
        if(ret == 0)
            emit s_InitOnceFinished();

        return ret;
    }
    virtual int _InitOnce();

    virtual int InitOnceInThread(); //线程中初始化(1次)

    //每次游戏开始前初始化,sr为随机数种子
    int GameInit(int sr = -1, QVariantMap param = QVariantMap())
    {
        int ret = _GameInit(sr, param);
        if(ret == 0)
            emit s_GameInitFinished();

        return ret;
    }
    virtual int _GameInit(int sr = -1, QVariantMap param = QVariantMap());


    //游戏开始调用
    //这是一个示例
    virtual _GameStatus GameBegin();
    //暂时无用
    virtual _GameStatus GameAdvance()
    {
        return CheckGameOver();
    }



    //游戏开始
    GameModel::_GameStatus GameStart(bool isStarted)
    {
        GameModel::_GameStatus ret = _GameStart(isStarted);

        if(ret != GameModel::Game_Status_Running)
            return ret;

        emit s_GameStart(isStarted);

        return ret;
    }
    virtual GameModel::_GameStatus _GameStart(bool isStarted)
    {
        m_eGameStatus = GameModel::Game_Status_Running;

        return gameStatus();
    }

    //游戏准备结束
    Q_INVOKABLE int sl_OverGame(_GameStatus status = Game_Status_GameOver, qint32 code = 0)
    {
        int ret = _OverGame(status, code);

        if(ret >= 0)
        {
            emit s_GameOver(status, code);

            m_eGameStatus = Game_Status_NotRunning;
            m_nGameStatusCode = 0;
        }

        return ret;
    }

    virtual int _OverGame(_GameStatus status = Game_Status_GameOver, qint32 code = 0);


    /*游戏循环(重写)
    virtual _GameStatus GameAdvance()
    {
        emit s_Debug("<font size=10>---Made By Pleafles---</font>");

        for(;;) //游戏主循环
        {
            if(gameStatus() != Game_Status_Running)
                break;
        }
        return setGameStatus(Game_Status_GameOver);
    }*/


    //设置游戏状态(会保存第一次退出状态)
    Q_INVOKABLE virtual _GameStatus setGameStatus(_GameStatus status, qint32 code)
    {
        if(m_eGameStatus == Game_Status_Running && status != Game_Status_Running)
        {
            m_eGameStatus = status;
            m_nGameStatusCode = code;
            emit s_Debug(tr("[GameModel]游戏状态设置:%1(%2)").arg(m_eGameStatus).arg(m_nGameStatusCode));
        }
        return m_eGameStatus;
    }


    //强制结束游戏时的处理
    virtual _GameStatus _TerminateGame(_GameStatus status = Game_Status_Terminated, qint32 code = 0)
    {
        //!!!注意:因为游戏退出,不一定会真正将线程结束(因为有些函数返回Game_Button_ERROR!!!)

        if(!isRunning())
            return gameStatus();


        //m_mutexNet.tryLock();
        //m_mutexQuestion.tryLock();

        //getDataList();
        //pMutexNet->lock();
        //m_Producer.comingNetDataSemaphore();
        //pMutexNet->unlock();
        //pMutexData->tryLock();
        //releaseDataList();
        //questionFinished();

        //sl_UserActionFinished();

        //quit();
        /*if(!wait(WAIT_GAME_TERMINATE_TIME))  //返回true:线程已经退出
        {
            terminate();
        }*/
        //if(bGameIsRunning)
        //    emit s_GameOver(status, nCode);


        qDebug() << "[GameModel]TerminateGame:" << status << code;
        //setGameStatus(status, code);
        //sl_OverGame(status, code);

        return status;
    }

    //检测游戏是否结束,返回Game_Status_Running或Game_Status_GameOver
    virtual _GameStatus CheckGameOver()
    {
        if(gameStatus() != Game_Status_Running)return gameStatus();

        if(0)
        {
            setGameStatus(Game_Status_GameOver, 0);
            sl_OverGame(Game_Status_GameOver, 0);
        }

        //return setGameStatus(Game_Status_GameOver);
        return gameStatus();
    }

    int isWin()
    {
        return 1;
    }

//框架(其他)

public:
    virtual void Sleep(unsigned long msec)
    {
        if(!m_bRunAtServer)
            this->thread()->msleep(msec);
    }

/*
public:
    virtual void Message(const QString& msg)
    {
        emit s_Message(msg);
    }

    virtual void Debug(const QString& msg)
    {
        qDebug() << msg;
        emit s_Debug(msg);
    }

    virtual void Critical(const QString& msg)
    {
        qCritical() << msg;
        emit s_Debug(msg);
    }

public:
//UI游戏框架
    virtual void WaitForUserAction()
    {
        m_waitForUserAction.wait(&m_mutexUserAction);
    }
    virtual void sl_UserActionFinished()
    {
        m_waitForUserAction.wakeAll();
    }
*/



//框架属性:
public:
    _GameStatus gameStatus() const
    {
        return m_eGameStatus;
    }

    bool netPlay() const
    {
        return m_bNetPlay;
    }


    bool isRunning() const
    {
        //先暂时用这个判断!!!
        //bool bGameIsRunning = this->isRunning();
        return gameStatus() == Game_Status_Running;
    }

//重载
protected:
    //virtual void run() Q_DECL_OVERRIDE;




//框架数据
private:
    bool        m_bInitOnce;   //是否初始化过
    bool        m_bInitOnceInThread;   //线程中是否初始化过

public:
    _GameStatus m_eGameStatus;      //游戏状态,结束,继续,强制退出,错误等
    qint32      m_nGameStatusCode;    //游戏状态码


//游戏外部设置:
    bool        m_bRunAtServer;     //是否在服务器运行（主要屏蔽sleep）
    bool        m_bLogicalMaster;   //是否游戏逻辑计算者
    bool        m_bNetPlay;


    _GameType   m_eGameType;        //游戏类型（玩法）
    int         m_nGameRandom;      //游戏随机数(局数)

    int         m_nPlayerCount;     //玩家数
    int         m_nMyID;            //本人ID(下标)

    QVariantMap m_GameConfig;       //游戏其他设置

/* UI游戏框架
    //QWaitCondition需要已锁的QMutex才能wait,wait时会将QMutex unlock!!
    QWaitCondition  m_waitForUserAction;
    QMutex          m_mutexUserAction;
*/
/* 网络游戏框架
    ProducerModel   m_Producer;
    TcpSocket       *pGameSocket;
    bool            netPlay;
*/

    friend class GameClientThreadModel;
};

#endif // GAMEMODEL_H
